
import React, { useEffect, useRef, useState } from 'react';
import { Space, Button } from 'antd';
import { throttle } from 'lodash';

type CanvasElementState = HTMLCanvasElement | null;
interface CoordinateState {
  x: number;
  y: number;
}
type EventsType = 'click' | 'move' | 'dblclick';

const CanvasImage = () => {

  // 当前坐标
  const [currentPoint, setCurrentPoint] = useState<CoordinateState | null>(null)
  const currentPointRef = useRef(currentPoint);
  currentPointRef.current = currentPoint
  // 当前图片地址
  const [currentUrl, setCurrentUrl] = useState<string>('')
  const currentUrlRef = useRef(currentUrl);
  currentUrlRef.current = currentUrl

  const drawFlag = useRef<boolean>(false);
  const drawTypeFlag = useRef<string>('area');

  const beginDraw = (type = 'area') => {
    drawFlag.current = true;
    drawTypeFlag.current = type;
  }

  // 保存画布
  const saveImage = throttle(() => {
    // 解决双击 会触发单击问题
    const canvasEle: CanvasElementState = document.querySelector('#myCanvas');
    if (canvasEle) {
      const url = canvasEle.toDataURL("image/png")

      setCurrentUrl(url)
    }
  }, 300)

  // 判断单点多次点击
  const flagClick = (point1: CoordinateState, point2: CoordinateState) => {
    const { x: x1, y: y1 } = point1;
    const { x: x2, y: y2 } = point2;

    if (x1 === x2 && y1 === y2) {
      return true;
    }
    return false;
  }


  // 画图
  const drawImage = (point: CoordinateState, type: EventsType) => {
    const { x, y } = point;
    const { current } = currentPointRef;

    // 双击
    if (type === 'dblclick') {
      setCurrentPoint(null)
      drawFlag.current = false;
    }

    // 单点多次点击
    if (current) {
      const moveFlag = flagClick(point, current);
      if (moveFlag) {
        return false
      }
    }

    const canvasEle: CanvasElementState = document.querySelector('#myCanvas');
    if (canvasEle) {
      const ctx = canvasEle.getContext('2d');

      if (ctx) {
        const img = new Image();
        img.src = currentUrlRef.current;

        ctx.clearRect(0, 0, canvasEle.width, canvasEle.height);
        ctx.beginPath();
        ctx.strokeStyle = '#ff0000';

        ctx.drawImage(img, 0, 0, canvasEle.width, canvasEle.height)

        // 移动至上一次的落点位置
        if (current) {
          ctx.moveTo(current.x, current.y);
          ctx.lineTo(x, y);
          // 闭合
          // ctx.closePath();
          // ③绘制
          ctx.stroke();
        }
      }
    }
    if (type !== 'move') saveImage();


    if (type === 'click') setCurrentPoint({ x, y })


    return true;
  }

  // 画矩形
  const drawRectangle = (point: CoordinateState, type: EventsType) => {
    const { x, y } = point;
    const { current } = currentPointRef;
    if (type === 'dblclick') {
      setCurrentPoint(null)
      drawFlag.current = false;

    }

    // 单点多次点击
    if (current) {
      const moveFlag = flagClick(point, current);
      if (moveFlag) {
        return false
      }
    }

    if (!current) {
      if (type === 'click') setCurrentPoint({ x, y })
    } else {
      const { x: x1, y: y1 } = current;
      const points = [
        { x: x1, y, },
        { x, y },
        { x, y: y1 }
      ]
      const canvasEle: CanvasElementState = document.querySelector('#myCanvas');
      if (canvasEle) {
        const ctx = canvasEle.getContext('2d');

        if (ctx) {
          const img = new Image();
          img.src = currentUrlRef.current;

          ctx.clearRect(0, 0, canvasEle.width, canvasEle.height);
          ctx.beginPath();
          ctx.strokeStyle = '#ff0000';

          ctx.drawImage(img, 0, 0, canvasEle.width, canvasEle.height)

          ctx.moveTo(x1, y1);
          for (let i = 0; i < points.length; i += 1) {
            ctx.lineTo(points[i].x, points[i].y);
          }
          // 闭合
          ctx.closePath();
          // ③绘制
          ctx.stroke();
        }
      }
    }
    if (type !== 'move') saveImage();
    return true

  }

  const startDraw = (e: MouseEvent, type: EventsType) => {
    if (drawFlag.current) {
      const x = e.offsetX; // 鼠标落下时的X
      const y = e.offsetY; // 鼠标落下时的Y
      if (drawTypeFlag.current === 'line') {
        drawImage({ x, y }, type)
      } else {
        drawRectangle({ x, y }, type)
      }
    }
  }

  // 给canvas画布添加事件
  const addCanvasEvents = () => {
    const canvasEle: CanvasElementState = document.querySelector('#myCanvas');
    if (canvasEle) {
      /**
       * 绑定点击事件
       */
      canvasEle.addEventListener('click', e => {
        startDraw(e, 'click');
      });
      /**
       * 绑定双击事件
       */
      canvasEle.addEventListener('dblclick', e => {
        startDraw(e, 'dblclick');
      });

      /**
       * 绑定鼠标移动事件
       */
      canvasEle.addEventListener('mousemove', e => {
        startDraw(e, 'move');
      });

    }
  }


  useEffect(() => {
    addCanvasEvents();



  }, [])


  return (
    <div>
      <Space size="small" direction="horizontal">
        <Button
          type="primary"
          onClick={() => {
            beginDraw('line');
          }}
        >
          画不规则线条
        </Button>
        <Button
          type="primary"
          onClick={() => {
            beginDraw('rectangle');
          }}
        >
          矩形
        </Button>
        <Button
          type="primary"
        // onClick={() => {
        //   clearRec();
        // }}
        >
          清除
        </Button>
      </Space>
      <canvas
        id='myCanvas'
        width={800}
        height={600}
        style={{ border: '1px solid red', marginTop: 24 }} />
    </div>
  )
}

export default CanvasImage;